package cloud.xuxiaowei.core.utils;

import cloud.xuxiaowei.core.properties.SecurityProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.List;

/**
 * Security 工具类
 *
 * @author xuxiaowei
 * @since 0.0.1
 */
@Slf4j
public class SecurityUtils {

	/**
	 * 获取用户名
	 * @return 返回用户名。如果返回 null，代表未登录（匿名用户）
	 */
	public static String getName() {
		SecurityContext context = SecurityContextHolder.getContext();
		Authentication authentication = context.getAuthentication();
		if (authentication instanceof AnonymousAuthenticationToken) {
			return null;
		}
		return authentication.getName();
	}

	/**
	 * 配置路径权限
	 * @param requestMatchers 请求路径匹配，用于权限控制
	 * @param authorizeRequests 授权请求
	 */
	public static void authorizeRequests(List<SecurityProperties.RequestMatcher> requestMatchers,
			ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests) {

		if (requestMatchers == null) {
			log.error("配置路径权限 为 null，请配置路径权限");
			return;
		}

		for (SecurityProperties.RequestMatcher requestMatcher : requestMatchers) {
			String[] patterns = requestMatcher.getPatterns();
			SecurityProperties.Access[] accesses = requestMatcher.getAccesses();
			String ipAddress = requestMatcher.getIpAddress();
			HttpMethod method = requestMatcher.getMethod();
			if (method == null) {
				for (SecurityProperties.Access access : accesses) {
					authorizeRequests.mvcMatchers(patterns).access(access.toString());
				}

				if (ipAddress != null) {
					authorizeRequests.mvcMatchers(patterns).hasIpAddress(ipAddress);
				}
			}
			else {
				for (SecurityProperties.Access access : accesses) {
					authorizeRequests.mvcMatchers(method, patterns).access(access.toString());
				}

				if (ipAddress != null) {
					authorizeRequests.mvcMatchers(method, patterns).hasIpAddress(ipAddress);
				}
			}
		}
	}

}
